//
//  LoginView.swift
//  IdleFish
//
//  Created by Ben on 2021/10/26.
//

import SwiftUI
import SDWebImageSwiftUI

enum LoginFocusField: Hashable {
    case userName
    
    case passWord
    
    case unsafePassWord
}

struct LoginView: View {
    
    
    // 这里介绍一下在SwiftUI3中，让TextField获取焦点以及控制焦点的一个方法
    @FocusState var loginFocusedField: LoginFocusField?
    
    @EnvironmentObject var userManagerVM: UserManagerViewModel
    @EnvironmentObject var hudState: BenHUDState
    
    // 本期视频接着完成登录界面的相关功能，先简单浏览一下up主对之前代码的改动
    var body: some View {
        VStack(alignment: .leading) {
            
            // 头部的功能按钮，关闭和更多
            LoginHeaderView()
            
            // 欢迎词
            LoginWelcomeAndRegisterView()
            
            // 用户名输入框
            // 接下来，需要在验证用户注册状态为已注册后，显示密码输入框，并让密码输入框获取焦点
            LoginInputUserNameView()
            // 在闲鱼中，当用户名输入框获得焦点的时候，密码输入框是隐藏状态
            // 密码输入框
            LoginInputPassWordView()
            
            // 检查用户名是否已注册按钮
            LoginCheckUserNameRegisterStatusButton()
            
            Spacer()
            
            // 其他登录方式
            LoginOtherLoginTypeView()
            
            // 登录需要勾选的协议框
            LoginUserPrivacyView()
            
            // 为了方便管理，up主把每个部分的view单独使用一个方法包装起来，便于后续的修改
        }
        .padding(.horizontal, 30)
        // 在view加载完成后让用户名输入框获取焦点，通常需要像下面这样设置一个延迟，否则会无法设置成功
        .onAppear(perform: {
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                loginFocusedField = .userName
            }
        })
        // 网络等待消息弹窗
        .waitHUD(isWait: $hudState.isWait) {
            // 定义网络连接等待hud的样子
            VStack(spacing: 8) {
                
                AnimatedImage(name: hudState.customImageName)
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width: 30, height: 30)
                
                if let msg = hudState.message {
                    
                    Text(msg)
                        .foregroundColor(.white)
                        .font(.system(size: 12, weight: .semibold))
                }
            }
            .padding(20)
            .background(
                
                RoundedRectangle(cornerRadius: 10)
                    .fill(.black)
            )
        }
        // 一般消息弹窗
        .showMessageHUD(isPresented: $hudState.isPresented) {
            
            Text(hudState.message ?? "")
                .foregroundColor(.white)
                .font(.system(size: 20, weight: .bold))
                .padding(.horizontal, 20)
                .padding(.vertical, 10)
                .background(
                    RoundedRectangle(cornerRadius: 10)
                        .fill(
                            Color.black.opacity(0.8)
                        )
                )
        }
    }
}

extension LoginView {
    // 所有LoginView的子view，都放在这个扩展里面
    
    // 在进行登录请求之前，还需要检查用户是否已经勾选了相关协议政策
    func LoginUserPrivacyView() -> some View {
        HStack(alignment: .center) {
            Button {
                userManagerVM.agrementCheckBoxIsSelected.toggle()
            } label: {
                Image(userManagerVM.agrementCheckBoxIsSelected ? "login_check_selected" : "login_check_normal")
                    .resize(size: CGSize(width: 10, height: 10), contentModel: .fit)
            }
            
            Text("您已阅读并同意")
                .foregroundColor(Color(hex: 0x868686))
            
            Group {
                Button {
                    
                } label: {
                    Text("《闲鱼社区用户服务协议》")
                }
                
                Button {
                    
                } label: {
                    Text("《隐私权政策》")
                }
            }
            .foregroundColor(Color(hex: 0x45B6FC))
        }
        .frame(maxWidth: .infinity)
        .font(.system(size: 12))
        .padding(.top, 30)
    }
    
    func LoginOtherLoginTypeView() -> some View {
        VStack(spacing: 20) {
            Text("其他登录方式")
                .font(.system(size: 12))
                .foregroundColor(Color(hex: 0xA3A3A3))
            
            HStack(spacing: 40) {
                
                
                Button {
                    
                } label: {
                    Image("taobao_logo_fastlogin")
                        .resize(size: CGSize(width: 50, height: 50), contentModel: .fit)
                }
                
                Button {
                    
                } label: {
                    Image("alipay_logo_fastlogin")
                        .resize(size: CGSize(width: 50, height: 50), contentModel: .fit)
                }
                
                
            }
        }
        .frame(maxWidth: .infinity)
    }
    
    func LoginCheckUserNameRegisterStatusButton() -> some View {
        Button {
            
            Task {
                // 在这里调用账号检查的方法
                if userManagerVM.canLogin {
                    
                    await userManagerVM.login()
                    
                } else if userManagerVM.canViretyUserNameRegisterStatus {
                    
                    await userManagerVM.verifyUserNameIsRegistered()
                    
                }
            }
            
        } label: {
            Text("确认")
                .font(.system(size: 20))
                .foregroundColor(Color(hex: 0x3A3329))
                .padding(.vertical, 10)
                .frame(maxWidth: .infinity)
                .background(
                    Capsule().fill(userManagerVM.canViretyUserNameRegisterStatus ? Color(hex: 0xFFE612) : Color(hex: 0xFDE26C))
                )
        }
        .padding(.top, 40)
        .disabled( loginFocusedField == .userName ? !userManagerVM.canViretyUserNameRegisterStatus : !userManagerVM.canLogin)
    }
    
    func LoginInputUserNameView() -> some View {
        ZStack(alignment: .bottom) {
            
            HStack {
                
                TextField("请输入手机号码/会员名/邮箱", text: $userManagerVM.loginUserName)
                    .font(.system(size: 20))
                    .padding(.bottom, 10)
                    .focused($loginFocusedField, equals: .userName)
                
                Button {
                    userManagerVM.loginUserName = ""
                } label: {
                    Image(systemName: "xmark")
                        .foregroundColor(.white)
                        .font(.system(size: 8, weight: .bold))
                        .padding(6)
                        .background(
                            Circle()
                                .fill(Color(hex: 0xC8C5C8))
                        )
                    
                }
                .opacity(userManagerVM.loginUserNameIsEmpty ? 0 : 1)
            }
            .padding(.horizontal, 4)
            .padding(.bottom, 4)
            // 当用户点击用户名输入框，隐藏密码输入框
            .onTapGesture {
                withAnimation {
                    userManagerVM.currFocusedField = .userName
                    userManagerVM.loginPassWord = ""
                    userManagerVM.showUnSafePassWord = false
                }
            }
            
            Divider()
                .foregroundColor(Color(hex: 0xE7E7E7))
        }
        .padding(.top, 40)
    }
    
    // 密码输入框
    // 关于密码输入框的显示、隐藏等逻辑到此结束，下期视频将完成用户登录获取token的功能，敬请期待。
    @ViewBuilder
    func LoginInputPassWordView() -> some View {
        
        if userManagerVM.currFocusedField == .passWord {
            ZStack(alignment: .bottom) {
                
                // 这个处理只是为了让view在刷新的时候，能够从userManagerVM更新到正确的值赋值给loginFocusedField
                GeometryReader { proxy -> AnyView in
                    
                    loginFocusedField = userManagerVM.currFocusedField ?? .userName
                    return AnyView(
                        Color.clear
                    )
                }
                .frame(height: 0)
                .hidden()
                
                HStack {
                    
                    // 切换明文密文输入框
                    if userManagerVM.showUnSafePassWord {
                        
                        TextField("请输入密码", text: $userManagerVM.loginPassWord)
                            .font(.system(size: 20))
                            .padding(.bottom, 10)
                            .focused($loginFocusedField, equals: .unsafePassWord)
                    } else {
                        SecureField("请输入密码", text: $userManagerVM.loginPassWord)
                            .font(.system(size: 20))
                            .padding(.bottom, 10)
                            .focused($loginFocusedField, equals: .passWord)
                    }
                    
                    
                    Button {
                        userManagerVM.loginPassWord = ""
                    } label: {
                        Image(systemName: "xmark")
                            .foregroundColor(.white)
                            .font(.system(size: 8, weight: .bold))
                            .padding(6)
                            .background(
                                Circle()
                                    .fill(Color(hex: 0xC8C5C8))
                            )
                        
                    }
                    .opacity(userManagerVM.loginPassWordIsEmpty ? 0 : 1)
                    
                    // 密码输入框还需要一个切换明文密文显示的按钮
                    
                    Button {
                        withAnimation {
                            userManagerVM.showUnSafePassWord.toggle()
                        }
                    } label: {
                        Image(systemName: userManagerVM.showUnSafePassWord == false ? "eye.slash" : "eye")
                            .foregroundColor(Color(hex: 0xC8C5C8))
                            .font(.system(size: 12, weight: .bold))
                        
                    }
                    
                }
                .padding(.horizontal, 4)
                .padding(.bottom, 4)
                
                Divider()
                    .foregroundColor(Color(hex: 0xE7E7E7))
            }
        }
        
        
        
        
    }
    
    func LoginWelcomeAndRegisterView() -> some View {
        VStack(alignment: .leading, spacing: 10) {
            Text("欢迎来到闲鱼")
                .font(.system(size: 30))
            
            HStack {
                Text("没有账户？")
                    .font(.system(size: 16))
                    .foregroundColor(.black.opacity(0.8))
                
                Button {
                    
                } label: {
                    Text("立即注册")
                        .font(.system(size: 16))
                        .foregroundColor(Color(hex: 0x45B6FC))
                }
                
            }
        }
        .padding(.top, 36)
    }
    
    func LoginHeaderView() -> some View {
        HStack {
            
            Button {
                userManagerVM.presentLoginView.toggle()
            } label: {
                Image(systemName: "xmark")
            }
            
            Spacer()
            
            Button {
                
            } label: {
                Text("更多")
            }
            
        }
        .font(.system(size: 18))
        .foregroundColor(.black)
    }
}

struct LoginView_Previews: PreviewProvider {
    static var previews: some View {
        LoginView()
    }
}
